package service

import (
	"context"
	"fmt"
	"iris-wms/apps/admin/web/dto/din"
	"iris-wms/apps/admin/web/dto/dout"
	"iris-wms/common/model"
	"iris-wms/common/pkg/db"
	"iris-wms/common/pkg/db/dao"

	"gorm.io/gen"
	"gorm.io/gorm"
)

var _ WmsGoodsCateService = (*wmsGoodsCateService)(nil)

type WmsGoodsCateService interface {
	Create(model.WmsGoodsCate) error
	Update(model.WmsGoodsCate) error
	DeleteByIdList([]uint) error
	GetList(din.WmsGoodsCateListIn) ([]*dout.WmsGoodsCateOut, error)
}

func NewWmsGoodsCateService() *wmsGoodsCateService {
	return &wmsGoodsCateService{}
}

type wmsGoodsCateService struct{}

func (impl *wmsGoodsCateService) Create(in model.WmsGoodsCate) (err error) {
	err = db.GDB1.Create(&in).Error
	return
}

func (impl *wmsGoodsCateService) Update(in model.WmsGoodsCate) (err error) {
	err = db.GDB1.Save(&in).Error
	return
}

func (impl *wmsGoodsCateService) DeleteByIdList(idList []uint) (err error) {
	err = db.GDB1.Transaction(func(tx *gorm.DB) error {
		if err = tx.Delete(&model.WmsGoodsCate{}, "id in ?", idList).Error; err != nil {
			return err
		}
		return nil
	})
	return
}

func (impl *wmsGoodsCateService) GetList(in din.WmsGoodsCateListIn) (rows []*dout.WmsGoodsCateOut, err error) {
	q := dao.Use(db.GDB1).WmsGoodsCateOut
	do := q.WithContext(context.Background())

	condList := make([]gen.Condition, 0)
	if in.Word != "" {
		condList = append(condList, q.Name.Like(fmt.Sprintf("%%%s%%", in.Word)))
	}
	if in.Enable > 0 {
		condList = append(condList, q.Enable.Eq(in.Enable))
	}
	if len(condList) > 0 {
		do = do.Where(condList...)
	}
	if rows, err = do.Where(q.ParentId.Eq(0)).Preload(q.Creator).Preload(q.Children).Find(); err != nil {
		return nil, err
	}
	err = impl.deep(rows)
	return
}

func (impl *wmsGoodsCateService) deep(parent []*dout.WmsGoodsCateOut) error {
	if len(parent) > 0 {
		for _, v1 := range parent {
			if len(v1.Children) > 0 {
				q := dao.Use(db.GDB1).WmsGoodsCateOut
				do := q.WithContext(context.Background())
				children, err := do.Where(q.ParentId.Eq(v1.ID)).Preload(q.Creator).Preload(q.Children).Find()
				if err != nil {
					return err
				}
				v1.Children = children
				if err := impl.deep(v1.Children); err != nil {
					return err
				}
			}
		}
	}
	return nil
}
